<template>
  <div class="mian">

    <div class="content">
      <div class="left">
        <div class="title">{{ruleForm.rnaType}} Expression</div>

        <el-form :model="ruleForm"
                 :rules="rules"
                 ref="ruleForm"
                 :hide-required-asterisk="true"
                 label-width="130px"
                 :label-position="'top'"
                 class="ruleForm">

          <el-row :gutter="20">
            <el-col :span="24">
              <el-form-item class="formItem" label="Host Kingdom :" prop="hostKingdom">
                <el-select class="inputWidth" v-model="ruleForm.hostKingdom" placeholder="" @change="kingdomSelect">
                  <el-option v-for="(n, idx) in hostGroups" :label="n.name" :value="idx" :key="idx"></el-option>
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>

          <el-row :gutter="20">
            <el-col :span="24">
              <el-form-item label="Host Species :" prop="host">
                <el-select class="inputWidth" v-model="ruleForm.host" placeholder="" @change="hostSelect">
                  <el-option v-for="(n, idx) in selectKindom.groups" :label="n.name" :value="idx"
                             :key="idx"></el-option>
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>

          <el-row :gutter="20">
            <el-col :span="24">
              <el-form-item label="Project :" prop="project">
                <el-select class="inputWidth" v-model="ruleForm.project" placeholder="">
                  <el-option v-for="(n, idx) in projectGroups" :label="n.project" :value="n.project"
                             :key="idx"></el-option>
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
        <el-button style="float: right" type="primary" @click="submitForm('ruleForm')">Search</el-button>
      </div>

      <div class="right">
        <div v-if="yArr.length > 0" class="download">
          <div class="btn" @click="downloadClick">
            <span class="titl">Download data</span>
            <i class="el-icon-download"></i>
          </div>
        </div>
        <div v-if="yArr.length > 0" class="tips">* Please click on an "Transcript ID" see the details below.</div>
        <div v-loading="loading" id="chartId" :style="{width: '100%', height: chartHeight + 'px'}"/>
      </div>
    </div>

    <dy-table :key="key" v-if="dyTableData.show"
              :loading="dyTableData.loading"
              :list="dyTableData.list"
              :total="dyTableData.total"
              :rnaType="dyTableData.rnaType"
              @refreshData="refreshDyData"
              id="dy-table"
              class="dy-table"
              ref="dyTable"/>
  </div>
</template>

<script>
import {getHotData, getProjectGroups, getHostsGroup, rnaList, exportEntries} from "../../api/expression";
  import DyTable from "../components/dyTable";

  export default {
    name: "expRNA",
    components: {DyTable},
    data() {
      return {
        ruleForm: {
          rnaType: null,
          hostKingdom: null,
          host: "",
          project: ""
        },
        rules: {
          hostKingdom: [
            {required: true, message: 'Host Kingdom can\'t be empty', trigger: 'change'}
          ],
          host: [
            {required: true, message: 'Host can\'t be empty', trigger: 'change'}
          ],
          project: [
            {required: true, message: 'Project can\'t be empty', trigger: 'change'}
          ],
        },
        hostGroups: [],
        projectGroups: [],
        selectKindom: [],
        loading: false,
        yArr: [],
        chartHeight: 800,

        dyTableData: {
          show: false,
          list: [],
          total: 0,
          loading: false,
          rnaType: null,

          params: {
            pageNum: 1,
            pageSize: 10,
          }
        },
        unit: "TPM",
        key: 0,
        isFristinto: true,
      }
    },
    mounted() {
      this.ruleForm.rnaType = this.$route.query.rnaType

      if (this.ruleForm.rnaType == 'mRNA' ||
          this.ruleForm.rnaType == 'lncRNA' ) {
        this.unit = "TPM"
      }else if (this.ruleForm.rnaType == 'circRNA') {
        this.unit = "Junction read counts"
      }else if (this.ruleForm.rnaType == 'sRNA') {
        this.unit = "RPM"
      }

      this.initChart()
      this.loadHostGroups()
    },
    methods: {
      initChart() {
        this.chart = this.$echarts.init(document.getElementById('chartId'))
        // y轴label 点击事件
        this.chart.on('click', (params) => {
          if(params.componentType == "yAxis"){
            this.yAxisCLick(params.value)
          }
        });
      },
      yAxisCLick(val) {
        this.key += 1;
        this.dyTableData.show = true
        this.dyTableData.rnaType = this.ruleForm.rnaType

        this.dyTableData.params = {
          hostKingdom: this.ruleForm.hostKingdom,
          host: this.ruleForm.host,
          project: this.ruleForm.project,
          rnaType: this.ruleForm.rnaType,
          transcriptId: val,
          pageNum: 1,
          pageSize: 10
        }

        this.getDyRnaListData()
      },
      refreshDyData(pageNum, pageSize) {
        this.dyTableData.params.pageNum = pageNum
        this.dyTableData.params.pageSize = pageSize

        this.getDyRnaListData()
      },
      async getDyRnaListData() {
        this.dyTableData.loading = true
        const res = await rnaList(this.dyTableData.params)
        if (res) {
          this.dyTableData.total = res.total
          this.dyTableData.list = res.rows;
        }
        this.dyTableData.loading = false

        console.log(this.dyTableData)
        this.$nextTick(() => {
          this.goDyTable()
        })
      },
      goDyTable() {
        this.$nextTick(() => {
          // 实现滚动效果
          let top = document.documentElement.scrollTop
          let endY = document.getElementById("dy-table").offsetTop
          const timeTop = setInterval(() => {
            document.body.scrollTop = document.documentElement.scrollTop = top += 20
            if (top >= endY) {
              clearInterval(timeTop);
            }
          }, 3);
        })
        // this.$nextTick(()=> {
        //   document.getElementById('dy-table').scrollIntoView({block: 'center'});
        // })
      },
      async downloadClick() {
        const data = await exportEntries(this.ruleForm)
        this.downloadFile(data, this.ruleForm.rnaType)
      },
      downloadFile(data, rnaType) {
        if (!data) {
          return
        }
        let url = window.URL.createObjectURL(new Blob([data]))
        let link = document.createElement('a')
        link.style.display = 'none'
        link.href = url

        let fileName = rnaType + "_" + this.ruleForm.project + '_expression.xlsx'
        link.setAttribute('download', fileName)
        document.body.appendChild(link)
        link.click()
      },
      async loadData() {
        this.loading = true
        const res = await getHotData(this.ruleForm)
        this.setOptions(res.data)
        this.loading = false
      },
      setOptions(data) {

        let visText = this.ruleForm.rnaType ==='circRNA' ? 'log10\n(Junction\n read counts)' : `log10(${this.unit})`

        let xArr = [];
        let yArr = [];
        let points = []
        let max = 0

        data.map(m => {
          max = m.val > max ? m.val : max;
          xArr.indexOf(m.x) > -1 ? '' : xArr.push(m.x)
          yArr.indexOf(m.y) > -1 ? '' : yArr.push(m.y)
          points.push([xArr.indexOf(m.x), yArr.indexOf(m.y), m.val])
        })
        this.yArr = yArr

        let option = {
          title: {
            text: `Expression value (in ${this.unit})`,
            left: 'center'
          },
          tooltip: {
            // 自定义修改悬浮内容
            formatter: (params) => {
              return `<div>
<div><span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${params.color};"></span>
<span>${yArr[params.data[1]] + ',' + params.name}</span></div>
<div>log10(${this.unit}) Value: ${params.data[2] == '-Infinity' ? 0 : params.data[2]}</div>
</div>`
            },
          },
          grid: {
            top: '70',
            left: '15%',
            right: "13%",
            bottom: "100"
          },
          xAxis: {
            name: 'Sample And \nCell/Tissue',
            type: 'category',
            data: xArr,
            splitArea: {
              show: true
            },
            axisLabel : {//坐标轴刻度标签的相关设置。
              show: false,
              fontSize: 10,
              rotate: 45,  //设置倾斜度
              formatter : function(params){
                var newParamsName = "";// 最终拼接成的字符串
                var paramsNameNumber = params.length;// 实际标签的个数
                var provideNumber = 15;// 每行能显示的字的个数
                var rowNumber = Math.ceil(paramsNameNumber / provideNumber);// 换行的话，需要显示几行，向上取整
                rowNumber = rowNumber > 2 ? 2 : rowNumber;
                /**
                 * 判断标签的个数是否大于规定的个数， 如果大于，则进行换行处理 如果不大于，即等于或小于，就返回原标签
                 */
                // 条件等同于rowNumber>1
                if (paramsNameNumber > provideNumber) {
                  /** 循环每一行,p表示行 */
                  for (var p = 0; p < rowNumber; p++) {
                    var tempStr = "";// 表示每一次截取的字符串
                    var start = p * provideNumber;// 开始截取的位置
                    var end = start + provideNumber;// 结束截取的位置
                    // 此处特殊处理最后一行的索引值
                    if (p == rowNumber - 1) {
                      // 最后一次不换行
                      tempStr = params.substring(start, paramsNameNumber);
                      if (paramsNameNumber - start > 3) {
                        tempStr = params.substring(start, start + provideNumber - 3) + '...';
                      }else {
                      tempStr = params.substring(start, paramsNameNumber);
                      }
                    } else {
                      // 每一次拼接字符串并换行
                      tempStr = params.substring(start, end) + "\n";
                    }
                    newParamsName += tempStr;// 最终拼成的字符串
                  }
                } else {
                  // 将旧标签的值赋给新标签
                  newParamsName = params;
                }
                //将最终的字符串返回
                return newParamsName
              }
            }
          },
          yAxis: {
            name: 'Transcript ID',
            type: 'category',
            data: yArr,
            triggerEvent: true,
            splitArea: {
              show: true
            },
            axisLabel : {//坐标轴刻度标签的相关设置。
              interval: 0,
              clickable:true,
            }
          },
          visualMap: {
            text: [visText],
            type: "continuous",
            textGap: 30,
            min: 0,
            max: max,
            calculable: true,
            orient: 'vertical',
            right: '0',
            top: 'center',
            itemHeight: 500,
            align: "right",
            inRange: {
              // color: ['#feffcf','#d0eea4', "#6dc3ad", "#2289b4"
              //   ,'#1c68a7', '#1b4595','#1a217d','#11427d']// 修改热力图的颜色 淡蓝色=>深蓝色的过度
              color: ['#56ff34','#86ff64', "#b1ff93", "#deffd0",
                "#fff"
                ,'#fbdacd', '#fd927a','#f54e37','#f90014']// 修改热力图的颜色 淡蓝色=>深蓝色的过度
            }
          },
          series: [
            {
              name: 'Punch Card',
              type: 'heatmap',
              data: points,
              label: {
                show: false
              },
              emphasis: {
                itemStyle: {
                  shadowBlur: 10,
                  shadowColor: 'rgba(0, 0, 0, 0.5)'
                }
              }
            }
          ]
        };

        this.chart.setOption(option)
        this.getChartHeight()
      },
      getChartHeight() {
        // 计算chart需要的高度
        let height = 13 * this.yArr.length + 200
        this.chartHeight = height > 800 ? height : 800
        this.chart.resize({
          width: 'auto',
          height: this.chartHeight + 'px'
        });
      },
      async loadHostGroups() {
        const res = await getHostsGroup({rnaType: this.ruleForm.rnaType})
        this.info = res.data;
        let arr = []
        for (let key in res.data) {
          let obj = {
            name: key,
            groups: []
          }
          res.data[key].map(n => {
            obj.groups.push({
              name: n
            })
          })

          // 按字母大小排序
          obj.groups.sort((a, b) => {
            return a.name.localeCompare(b.name);
          });
          arr.push(obj)
        }

        // 按字母大小排序
        arr.sort((a, b) => {
          if (a.name == "None") {
            return 1
          }
          return a.name.localeCompare(b.name);
        });

        this.hostGroups = arr

        if (this.isFristinto) {
          this.$nextTick(() => {
            this.kingdomSelect(0)
            this.hostSelect(4)
          })
        }
      },
      kingdomSelect(n) {
        this.ruleForm.hostKingdom = null
        this.ruleForm.host = null
        this.ruleForm.project = null

        this.selectKindom = this.hostGroups[n];
        this.ruleForm.hostKingdom = this.selectKindom.name
      },
      async hostSelect(n) {
        this.ruleForm.project = null
        this.ruleForm.host = this.selectKindom.groups[n].name

        const res = await getProjectGroups(this.ruleForm)
        this.projectGroups = res.data

        if (this.isFristinto) {
          this.isFristinto = false
          this.ruleForm.project = this.projectGroups[0].project
          this.submitForm('ruleForm')
        }
      },
      submitForm(formName) {
        this.$refs[formName].validate((valid) => {
          if (valid) {
            this.loadData()
          } else {
            console.log('error submit!!');
            return false;
          }
        });
      },
      resetForm(formName) {
        this.$refs[formName].resetFields();
      }
    }
  }
</script>

<style lang="stylus" scoped>

  .mian {
    width 1170px
    margin-top 20px
    font-family: Times New Roman;

    .dy-table {
      margin-top 50px
    }

    .content {
      margin-top 30px
      display flex

      .title {
        font-size 28px
        text-align left
        margin-bottom 20px
        padding 15px 0
        color #11427D
        font-weight 800
      }

      .inputWidth /deep/ {
        width 100%

        .el-input.is-active .el-input__inner, .el-input__inner:focus {
          border-color: #11427D;
          outline: 0;
        }
      }

      .el-button--primary /deep/ {
        background-color: #11427D;
        border-color: #11427D;
        border-radius 7px

        span, i {
          font-weight 700
        }
      }

      .el-button:hover {
        color: #11427D;
        border-color: #11427D;
        background-color: #e0e5ef;
      }

      .left {
        width 30%
        padding: 30px;
        border-radius 6px
        max-height 550px
        box-shadow: 0 2px 12px 0 rgba(193, 193, 193, 0.39);

        position: sticky;
        top: 30px;
        left: 0;
      }

      .tips {
        position absolute
        top 75px
        font-size 14px
        right 20px
        color #8f8f8f
      }

      .right /deep/ {
        flex 1
        padding-left 30px
        position relative
        //设置图标颜色
        .el-loading-spinner .path {
          stroke: #11427D;
        }
        .download {
          display flex
          justify-content flex-end

          .btn {
            cursor pointer
          }
          .titl {
            display inset-block
            margin-right 8px
          }
          i {
            padding 8px
            background-color #eaeaea
          }
        }
      }
    }
  }

</style>
